import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fmin_bfgs, fminbound, brute

# 定义目标函数
def func(x):
    return x**2 + 10 * np.sin(x)

# 使用 fmin_bfgs 方法找到最小值
x0_bfgs = 0  # 初始猜测
res_bfgs = fmin_bfgs(func, x0_bfgs, disp=False)
x_bfgs, f_bfgs = res_bfgs[0], func(res_bfgs[0])

# 使用 fminbound 方法找到最小值
res_bound = fminbound(func, -10, 10, disp=False)
x_bound, f_bound = res_bound, func(res_bound)

# 使用 brute 方法找到最小值
res_brute = brute(func, ranges=[(-10,10)], args=(), Ns=20, full_output=0, 
          disp=False, workers=1)
x_brute, f_brute = res_brute[0], func(res_brute[0])

# 打印结果
print(f"fmin_bfgs: x = {x_bfgs}, f(x) = {f_bfgs}")
print(f"fminbound: x = {x_bound}, f(x) = {f_bound}")
print(f"brute: x = {x_brute}, f(x) = {f_brute}")

# 绘制目标函数的图形
x_plot = np.linspace(-10, 10, 400)
y_plot = func(x_plot)

plt.figure(figsize=(10, 6))
plt.plot(x_plot, y_plot, label='f(x) = x^2 + 10 sin(x)')
plt.scatter([x_bfgs, x_bound, x_brute], [f_bfgs, f_bound, f_brute], color='red', label='Minimum points')
plt.legend()
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Optimization Results')
plt.show()